package com.mswordutil.export;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.Borders;
import org.apache.poi.xwpf.usermodel.BreakType;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;

import com.mswordutil.markdown.Block;
import com.mswordutil.markdown.Processor;
import com.mswordutil.markdown.ValuePart;
import com.mswordutil.util.ImgHelper;

public class Poi3Decorator implements Decorator{
	
	public void decorate(XWPFParagraph paragraph, Block block) {
		paragraph.setAlignment(ParagraphAlignment.LEFT);
		switch (block.getType()) {
		case CODE:
			codeParagraph(paragraph, block.getValueParts());
			break;
		case HEADLINE:
			headerParagraph(paragraph, block.getValueParts(), block.getLevel());
			break;
		case BLOCKQUOTE:
			blockquoteParagraph(paragraph, block.getValueParts());
			break;
		case IMG:
			imgParagraph(paragraph, block.getValueParts());
			break;
		default:
			commonTextParagraph(paragraph, block.getValueParts());
			break;
		}
	}

	private void codeParagraph(XWPFParagraph p, ValuePart[] valueParts){

        p.setBorderTop(Borders.BASIC_THIN_LINES);
        p.setBorderBottom(Borders.BASIC_THIN_LINES);
		p.setBorderLeft(Borders.BASIC_THIN_LINES);
		p.setBorderRight(Borders.BASIC_THIN_LINES);

        XWPFRun r = p.createRun();
        r.setBold(false);
        r.setText(valueParts[0].getValue());
        r.setFontFamily("Courier");
	}
	
	private void headerParagraph(XWPFParagraph p, ValuePart[] valueParts, int levle){
		
		XWPFRun r = p.createRun();
        r.setText(valueParts[0].getValue());
        r.setFontSize(30 - 2*levle);
        r.setBold(true);
	}

	private void blockquoteParagraph(XWPFParagraph p, ValuePart[] valueParts){
		p.setBorderLeft(Borders.BASIC_THIN_LINES);
		
		XWPFRun r = p.createRun();
        r.setText(valueParts[0].getValue());
	}
	
	private void imgParagraph(final XWPFParagraph p, ValuePart[] valueParts){
		final String imgFile = valueParts[0].getValue();
		ImgHelper helper = new ImgHelper() {
			@Override
			public void setIntoWord(InputStream is) {
				XWPFRun r = p.createRun();
				if(is==null){	//如果图片不存在，则直接输出内容
			        r.setText("图片地址："+imgFile);
			        return;
				}
				
		        r.setText(imgFile);
		        
	        	ByteArrayOutputStream baos = null;
	        	InputStream imgIs = null;
		        try {
		        	baos = inputStream2ByteArrayOutputStream(is);     

		        	InputStream tmpIs = new ByteArrayInputStream(baos.toByteArray());
		        	int ia[] = computeWidthHeight2Show(getImgWidthHeight(tmpIs));
		        	
		        	imgIs = new ByteArrayInputStream(baos.toByteArray());
		        	r.addPicture(imgIs, typeOfImg(imgFile), imgFile, Units.toEMU(ia[0]), Units.toEMU(ia[1]));
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					closeStream(baos, imgIs);
				}
		        r.addBreak(BreakType.PAGE);
			}
		};
		helper.setImgByUrl(imgFile);
	}
	
	private void commonTextParagraph(XWPFParagraph p, ValuePart[] valueParts){
		
		XWPFRun r = p.createRun();
        r.setText(valueParts[0].getValue());
        r.setFontSize(14);
        r.setBold(false);
        
	}
	
	private int typeOfImg(String imgFile){
		int format = XWPFDocument.PICTURE_TYPE_JPEG;

        if(imgFile.endsWith(".emf")){
        	format = XWPFDocument.PICTURE_TYPE_EMF;
        }else if(imgFile.endsWith(".wmf")) {
        	format = XWPFDocument.PICTURE_TYPE_WMF;
        }else if(imgFile.endsWith(".pict")) {
        	format = XWPFDocument.PICTURE_TYPE_PICT;
        }else if(imgFile.endsWith(".jpeg") || imgFile.endsWith(".jpg")) {
        	format = XWPFDocument.PICTURE_TYPE_JPEG;
        }else if(imgFile.endsWith(".png")) {
        	format = XWPFDocument.PICTURE_TYPE_PNG;
        }else if(imgFile.endsWith(".dib")) {
        	format = XWPFDocument.PICTURE_TYPE_DIB;
        }else if(imgFile.endsWith(".gif")) {
        	format = XWPFDocument.PICTURE_TYPE_GIF;
        }else if(imgFile.endsWith(".tiff")) {
        	format = XWPFDocument.PICTURE_TYPE_TIFF;
        }else if(imgFile.endsWith(".eps")) {
        	format = XWPFDocument.PICTURE_TYPE_EPS;
        }else if(imgFile.endsWith(".bmp")) {
        	format = XWPFDocument.PICTURE_TYPE_BMP;
        }else if(imgFile.endsWith(".wpg")) {
        	format = XWPFDocument.PICTURE_TYPE_WPG;
        }else {
            System.err.println("Unsupported picture: " + imgFile + ". Expected emf|wmf|pict|jpeg|png|dib|gif|tiff|eps|bmp|wpg");
        }
        return format;
	}
	
	private int maxWidth = 400;
	private int[] computeWidthHeight2Show(int[] ia){
		if(ia==null || ia.length<2){
			return new int[]{100, 100};
		}
    	int w = ia[0];
    	int h = ia[1];
    	if(w>maxWidth){
    		double d = ((double)w)/maxWidth;
    		h = (int)(((double)h)/d);
    		w = maxWidth;
    	}
    	return new int[]{w, h};
	}
	
	private void closeStream(ByteArrayOutputStream baos, InputStream imgIs){
		if(baos!=null){
			try {
				baos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if(imgIs!=null){
			try {
				imgIs.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) throws FileNotFoundException {
		Processor.process("#大标题\n###小标题 \n```\npublic void main()\n{\n    Syetem.out.println(\"Hello World!\");\n}\n```\n正文，这里是正文哦\n> 来一段引用的内容，这个内容很长很长！！！\n![输入图片说明](https://static.oschina.net/uploads/img/201504/21151519_mMbu.png \"在这里输入图片标题\")\n再来一段正文\n正文22222", 
				"/Users/cevin/Downloads/simple4.docx");
	}
}
